const express = require("express"); // Web框架
const http = require("http"); // HTTP服务器
const socketIo = require("socket.io"); // WebSocket实时通信
const aedes = require("aedes"); // MQTT broker
const net = require("net"); // TCP网络服务
const cors = require("cors"); // 跨域处理

// 创建Express应用
const app = express();
const server = http.createServer(app);

// 配置CORS
app.use(cors());
app.use(express.json());

// 静态文件服务（为前端提供服务）
app.use(express.static(__dirname));

// 创建MQTT broker
const broker = aedes();

// MQTT broker事件监听
broker.on("client", (client) => {
  console.log(`MQTT客户端连接: ${client.id}`);
});

broker.on("clientDisconnect", (client) => {
  console.log(`MQTT客户端断开: ${client.id}`);
});

broker.on("publish", (packet, client) => {
  if (client) {
    console.log(`收到消息: ${packet.payload.toString()} 来自: ${client.id}`);
  }
});

// 创建MQTT服务器
const mqttServer = net.createServer(broker.handle);
const MQTT_PORT = 1883;

mqttServer.listen(MQTT_PORT, () => {
  console.log(`MQTT Broker运行在端口 ${MQTT_PORT}`);
});

// 创建Socket.IO服务器
const io = socketIo(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"],
  },
});

// 存储在线用户
const onlineUsers = new Map();

// Socket.IO连接处理
io.on("connection", (socket) => {
  console.log(`WebSocket客户端连接: ${socket.id}`);

  // 用户加入聊天室
  socket.on("join", (userData) => {
    const { username, room } = userData;
    socket.username = username;
    socket.room = room;

    // 加入房间
    socket.join(room);

    // 存储用户信息
    onlineUsers.set(socket.id, { username, room, socketId: socket.id });

    // 通知其他用户有新用户加入
    socket.to(room).emit("user-joined", {
      username,
      message: `${username} 加入了聊天室`,
      timestamp: new Date().toISOString(),
    });

    // 发送当前房间的在线用户列表
    const roomUsers = Array.from(onlineUsers.values())
      .filter((user) => user.room === room)
      .map((user) => user.username);

    io.to(room).emit("online-users", roomUsers);

    console.log(`用户 ${username} 加入房间 ${room}`);
  });

  // 处理聊天消息
  socket.on("chat-message", (messageData) => {
    const { message, room } = messageData;
    const username = socket.username;

    if (username && room) {
      const fullMessage = {
        username,
        message,
        timestamp: new Date().toISOString(),
        type: "chat",
      };

      // 广播消息到房间内所有用户
      io.to(room).emit("chat-message", fullMessage);

      console.log(`[${room}] ${username}: ${message}`);
    }
  });

  // 用户正在输入
  socket.on("typing", (data) => {
    const { room } = data;
    const username = socket.username;

    if (username && room) {
      socket.to(room).emit("user-typing", { username });
    }
  });

  // 用户停止输入
  socket.on("stop-typing", (data) => {
    const { room } = data;
    const username = socket.username;

    if (username && room) {
      socket.to(room).emit("user-stop-typing", { username });
    }
  });

  // 客户端断开连接
  socket.on("disconnect", () => {
    const userInfo = onlineUsers.get(socket.id);

    if (userInfo) {
      const { username, room } = userInfo;

      // 从在线用户列表中移除
      onlineUsers.delete(socket.id);

      // 通知其他用户
      socket.to(room).emit("user-left", {
        username,
        message: `${username} 离开了聊天室`,
        timestamp: new Date().toISOString(),
      });

      // 更新在线用户列表
      const roomUsers = Array.from(onlineUsers.values())
        .filter((user) => user.room === room)
        .map((user) => user.username);

      io.to(room).emit("online-users", roomUsers);

      console.log(`用户 ${username} 离开了房间 ${room}`);
    }

    console.log(`WebSocket客户端断开: ${socket.id}`);
  });
});

// API路由
app.get("/api/health", (req, res) => {
  res.json({
    status: "running",
    mqttPort: MQTT_PORT,
    websocketPort: PORT,
    timestamp: new Date().toISOString(),
  });
});

// 获取在线用户统计
app.get("/api/stats", (req, res) => {
  const stats = {
    totalUsers: onlineUsers.size,
    rooms: {},
  };

  // 按房间统计用户
  for (const user of onlineUsers.values()) {
    if (!stats.rooms[user.room]) {
      stats.rooms[user.room] = [];
    }
    stats.rooms[user.room].push(user.username);
  }

  res.json(stats);
});

// 启动HTTP服务器
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`HTTP服务器运行在端口 ${PORT}`);
  console.log(`访问地址: http://localhost:${PORT}`);
});

// 优雅关闭
process.on("SIGINT", () => {
  console.log("正在关闭服务器...");
  server.close(() => {
    mqttServer.close(() => {
      console.log("服务器已关闭");
      process.exit(0);
    });
  });
});
